"""
Case Type   : 资源池化故障模式库
Case Name   : 套接字文件无权限-数据库运行时，修改套接字文件权限
Create At   : 2025/04
Owner       : haomeng
Description :
    1、查看集群状态
    2、运行tpcc业务
    3、查看套接字文件路径,修改文件权限不可用
    4、查看业务运行情况
    5、gsql方式直连数据库执行sql语句
    6、重启集群，查看集群状态
    7、修改套接字文件权限
    8、恢复集群状态
Expect      :
    1、集群状态正常
    2、运行业务成功
    3、修改套接字文件权限成功
    4、业务运行正常无影响
    5、直连数据库执行sql语句失败
    6、重启集群失败，集群状态异常
    7、套接字文件权限恢复正常
    8、恢复集群状态成功
History     :
"""

import os
import time
import unittest

from testcase.utils.Common import Common
from testcase.utils.CommonSH import CommonSH
from testcase.utils.ComThread import ComThread
from testcase.utils.Constant import Constant
from testcase.utils.Logger import Logger
from yat.test import Node
from yat.test import macro

class SSFauleMode(unittest.TestCase):

    def setUp(self):
        self.log = Logger()
        self.log.info(f'----{os.path.basename(__file__)} start----')
        self.user_node = [Node(node='PrimaryRoot'), Node(node='PrimaryDbUser')]
        self.pri_sh = CommonSH('PrimaryDbUser')
        self.com = Common()
        self.constant = Constant()
        self.socket_param = 'unix_socket_directory'

    def test_ss_faule(self):
        text = '-----step1:查看集群状态;  expect:集群状态正常-----'
        self.log.info(text)

        status = self.pri_sh.exec_cm_ctl('query', '-Cv')
        self.log.info(status)
        self.assertIn('Normal', status, '集群状态异常')

        text = '-----step2:执行tpcc读写业务  expect:业务执行成功-----'
        self.log.info(text)

        tpcc_cmd = f'./runBenchmark.sh {macro.PROPS_FILENAME}'
        self.log.info(tpcc_cmd)

        tpcc_execute = ComThread(self.com.start_tpcc, args=(self.user_node[0],
                                                               f'{macro.TPCC_PATH}',
                                                               tpcc_cmd))
        tpcc_execute.setDaemon(True)
        tpcc_execute.start()

        text = '-----step3:删除主节点套接字文件  expect:删除成功-----'
        self.log.info(text)

        socket_dir = self.com.show_param(self.socket_param)
        self.log.info(socket_dir)
        self.assertIn('mppdb', socket_dir, '获取套接字文件路径失败')

        get_file_list = self.user_node[1].sh(f'ls -al {socket_dir};').result()
        self.log.info(get_file_list)
        socket_file_name = ''
        for file in get_file_list.split():
            self.log.info(file)
            if (self.user_node[1].db_port not in file) or ('lock' in file):
                pass
            else:
                socket_file_name = file

        socket_file = os.path.join(socket_dir, socket_file_name)
        delete = f'chmod 000 {socket_file}; ls -al {socket_file};'
        self.log.info(delete)

        delete_execute = ComThread(self.com.get_sh_result, args=(self.user_node[1], delete))
        delete_execute.setDaemon(True)
        delete_execute.start()

        text = '-----step4:查看业务运行情况  expect:业务运行正常无影响-----'
        self.log.info(text)

        tpcc_execute.join(10 * 60)
        ret1 = tpcc_execute.get_result()
        self.log.info(ret1)
        self.assertIn('Session End', ret1, 'tpcc执行失败')

        delete_execute.join(10 * 60)
        ret2 = delete_execute.get_result()
        self.log.info(ret2)
        self.assertIn('s-----', ret2, '修改套接字文件权限失败')

        text = '-----step5:gsql方式直连数据库执行sql语句  expect:直连数据库执行sql语句失败-----'
        self.log.info(text)

        sql_res = self.user_node[1].sh(f'source {macro.DB_ENV_PATH};'
                                       f'gsql -d {self.user_node[1].db_name} '
                                       f'-p {self.user_node[1].db_port} '
                                       f'-c "select 1;"').result()
        self.log.info(sql_res)
        self.assertIn('failed to connect', sql_res, '连接数据库成功')

        text = '-----step6:重启集群，查看集群状态  expect:重启失败，集群状态异常-----'
        self.log.info(text)

        restart = self.pri_sh.exec_cm_ctl('stop;', 'cm_ctl start -t 30')
        self.log.info(restart)
        self.assertIn(self.constant.cm_stop_success_msg, restart, '集群重启失败')
        self.assertIn(self.constant.cm_start_success_msg, restart, '集群重启失败')

        status = self.pri_sh.exec_cm_ctl('query', '-Cv')
        self.log.info(status)
        self.assertIn('cluster_state   : Normal', status, '集群重启失败')

        text = '-----step7:恢复套接字文件权限  expect:恢复套接字文件权限成功-----'
        self.log.info(text)

        check = f'chmod 700 {socket_file}; ls -al {socket_file};'
        self.log.info(check)
        res = self.user_node[1].sh(check).result()
        self.log.info(res)
        self.assertIn('srwx', res, '套接字文件权限异常')

    def tearDown(self):
        text = '-----step8:恢复集群状态  expect:恢复集群状态成功-----'
        self.log.info(text)

        restart = self.pri_sh.exec_cm_ctl('start')
        self.log.info(restart)

        status = self.pri_sh.exec_cm_ctl('query', '-Cv')
        self.log.info(status)

        if 'P Primary' not in status:
            switch = self.pri_sh.exec_cm_ctl('switchover', '-a')
            self.log.info(switch)
        self.assertIn('Normal', status, '集群重启失败')
        status2 = self.pri_sh.exec_cm_ctl('query', '-Cv')
        self.log.info(status2)
        self.assertIn('P Primary', status2, '集群状态异常')
        self.log.info(f'----{os.path.basename(__file__)} end----')
